﻿@using CID.Web.Support
@using CID.Web.Models.Operations
@model EnvironmentViewModel

<div id="Tabs">
    <ul>
        <li><a href="#General">General</a></li>
        <li><a href="#Assignments">Assignments</a></li>
    </ul>
    <div id="General">
        @using (Html.BeginForm()) {
            @Html.ValidationSummary(true)
            <div class="editor-label">
                @Html.LabelFor(model => model.Name)
            </div>
            <div class="editor-field">
                @Html.KOTextBoxFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.Description)
            </div>
            <div class="editor-field">
                @Html.KOTextAreaFor(model => model.Description)
                @Html.ValidationMessageFor(model => model.Description)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.Responsible)
            </div>
            <div class="editor-field">
                @Html.KODropDownListForEntity(m => m.ResponsibleId, Model.AvailableUsers, Model.ResponsibleId)
                @Html.ValidationMessageFor(model => model.ResponsibleId)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.IsProduction)
            </div>
            <div class="editor-field">
                @Html.KOCheckBoxFor(model => model.IsProduction)
                @Html.ValidationMessageFor(model => model.IsProduction)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.Enabled)
            </div>
            <div class="editor-field">
                @Html.KOCheckBoxFor(model => model.Enabled)
                @Html.ValidationMessageFor(model => model.Enabled)
            </div>

            @Html.KOHiddenFor(model => model.Id)
        }
    </div>
    <div id="Assignments">
        <div data-bind="template: {name: 'AssignmentEditorTemplate', data: EditingAssignment, afterRender: OnAssignmentEditorTemplateRender}"></div>
        <table>
            <thead>
                <tr>
                    <th>
                        Server
                    </th>
                    <th>
                        Role
                    </th>
                    <th>
                    </th>
                </tr>
            </thead>
            <tbody data-bind="template: {name: 'AssignmentDisplayTemplate', foreach: Assignments}">
            </tbody>
        </table>
        <p><input type="button" value="Add New" data-bind="click: NewAssignment" /></p>
    </div>
    <p> <input type="Button" value="Save" data-bind="click: Save" /> </p>
</div>

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script id="AssignmentDisplayTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>${Server}</td>
        <td>${ServerRole}</td>
        <td><input type="button" value="Delete" data-bind="click: Delete" /></td>
    </tr>
</script>

<script id="AssignmentEditorTemplate" type="text/x-jquery-tmpl">
    @Html.KOPartialChildEditor("AssignmentEditor", "Assignment", Model.NewServerAssignment())
</script>


<script type="text/javascript">
    $(document).ready(function () {
        $("#Tabs").tabs();
        viewModel.Load();
        ko.applyBindings(viewModel);
    });

    function MapAssignment(options) {
        var a = options.data;
        return new Assignment(a.Id, a.EnvironmentId, a.Environment, a.ServerId, a.Server, a.ServerRoleId, a.ServerRole);
    }

    function Assignment(id, environmentId, environment, serverId, server, serverRoleId, serverRole) {
        this.Id = ko.observable(id);
        this.EnvironmentId = ko.observable(environmentId)
        this.Environment = ko.observable(environment)
        this.ServerId = ko.observable(serverId);
        this.Server = ko.observable(server);
        this.ServerRoleId = ko.observable(serverRoleId);
        this.ServerRole = ko.observable(serverRole);
        this.Selected = ko.observable(false);
        this.Editing = ko.observable(false);
        this.IsValid = ko.dependentObservable(function () {
            return ((this.EnvironmentId() == viewModel.Id()) && this.ServerId() && this.ServerRoleId())
        }, this);
        this.Select = function () {
            if (viewModel.SelectedAssignment()) viewModel.SelectedAssignment().Unselect();
            this.Selected(true);
            viewModel.SelectedAssignment(this);
        };
        this.Unselect = function () {
            if (this.Selected()) {
                this.Selected(false);
                viewModel.SelectedAssignment(null);
            }
        };
        this.Edit = function () {
            this.Select();
            this.Editing(true);
            viewModel.BeginEdit(this);
        };
        this.Delete = function () {
            viewModel.RemoveAssignment(this);
        };
        this.UpdateWith = function (assignment) {
            this.Id(assignment.Id());
            this.EnvironmentId(assignment.EnvironmentId());
            this.Environment(assignment.Environment());
            this.ServerId(assignment.ServerId());
            this.Server(assignment.Server());
            this.ServerRoleId(assignment.ServerRoleId());
            this.ServerRole(assignment.ServerRole());
        };
        this.Apply = function () {
            viewModel.SelectedAssignment().UpdateWith(this());
            viewModel.EndEdit();
        };
        this.Cancel = function () {
            viewModel.EndEdit();
        };
    }

    var viewModel = {
        Id: ko.observable(),
        Name: ko.observable(),
        Description: ko.observable(),
        IsProduction: ko.observable(),
        Enabled: ko.observable(),
        ResponsibleId: ko.observable(),
        Assignments: ko.observableArray([]),
        SelectedAssignment: ko.observable(),
        EditingAssignment: ko.observable(),
        BeginEdit: function (assignment) {
            var asgmt = new Assignment(0, this.Id(), this.Name(), 0, "", 0, "");
            asgmt.UpdateWith(assignment);
            this.EditingAssignment(asgmt);
        },
        EndEdit: function () {
            this.SelectedAssignment().Editing(false);
            this.EditingAssignment(null);
        },
        AddAssignment: function (assignment) {
            this.Assignments.push(assignment);
        },
        NewAssignment: function () {
            var assignment = new Assignment(0, this.Id(), this.Name(), 0, "", 0, "");
            this.AddAssignment(assignment);
            assignment.Edit();
            return assignment;
        },
        RemoveAssignment: function (assignment) {
            if (assignment.Editing()) this.EditingAssignment().Cancel();
            if (assignment.Selected()) assignment.Unselect();

            this.Assignments.destroy(assignment);
        },
        OnAssignmentEditorTemplateRender: function (elements) {
            //when the editor template is rendered, the form it contains needs to be reparsed to attach it to the unobstrusive validation
            var formSelector = elements.first().parent().find('form');
            if (formSelector.is('form')) {
                $.validator.unobtrusive.parseDynamicContent(formSelector);
                formSelector.validate();
                formSelector.valid();
            }
        },
        Load: function () {
            var mapping = {
                'Assignments': {
                    create: function (options) { return MapAssignment(options); }
                }
            }
            ko.mapping.fromJS(@Html.JSON(Model), mapping, this);
        },
        Save: function () {
            var viewModelJSON = ko.toJSON(ko.mapping.toJS(this));
            $.ajax({
                url: this.PostUrl(),
                data: viewModelJSON,
                type: 'POST',
                contentType: 'application/json;',
                dataType: 'json',
                success: function (response) {
                    switch (response.Type) {
                        case "Redirect":
                            window.location.href = response.Url;
                            break;
                        case "View":
                            //TODO: display error in the summary error pane. Need to research how that's done with unobtrusive validation
                            alert(response.ModelError);
                            break;
                    }
                }
            });
        }
    };

    ko.bindingHandlers.valueText = new ValueTextHandler();
</script>